#ifndef ACCOUNT_HH
#define ACCOUNT_HH

#include <iostream>
#include <string>
#include <vector>

namespace MiniBank 
{
    //Transaction
    class Transaction 
    {
    public:
        Transaction(const std::string& type, double amount, const std::string& note);
        std::string getType() const;
        double getAmount() const;
        std::string getNote() const;
        std::string getTransactionID() const;
        static std::string generateTransactionID();

    private:
        std::string transactionType;
        double transactionAmount;
        std::string transactionNote;
        std::string transactionID;
    };

    //Account
    class Account 
    {
    protected:
        std::string accountID;
        std::string accountHolder;
        double balance;
        std::vector<Transaction> transactions;

    public:
        Account(const std::string& id, const std::string& holder, double initialBalance);
        virtual ~Account();
        std::string getAccountID() const;
        std::string getAccountHolder() const;
        double getBalance() const;
        const std::vector<Transaction>& getTransactions() const;
        virtual void deposit(double amount, const std::string& note = "");
        virtual bool withdraw(double amount, const std::string& note = "");
        virtual bool transfer(Account& target, double amount, const std::string& note = "");
        virtual void displayInfo() const;
        virtual void generateReport(const std::string& filename) const;
        Account& operator+=(double amount);
        Account& operator-=(double amount);
    };

    //SavingAccount-Inherit Account
    class SavingsAccount : public Account 
    {
    public:
        SavingsAccount(const std::string& id, const std::string& holder, double initialBalance);
        bool transfer(Account& target, double amount, const std::string& note = "") override;
        void displayInfo() const override;
    };

    //CheckingAccount-Inherit Account
    class CheckingAccount : public Account 
    {
    public:
        CheckingAccount(const std::string& id, const std::string& holder, double initialBalance);
        void deposit(double amount, const std::string& note = "") override;
        bool withdraw(double amount, const std::string& note = "") override;
        bool transfer(Account& target, double amount, const std::string& note = "") override;
        void displayInfo() const override;
    };

} 

#endif 
